import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { BaseService } from '@wwjCommon/base/base.service';
import { CacheService } from '@wwjCommon/cache/cache.service';
import { LoggingService } from '@wwjCommon/logging/logging.service';
import { UploadService } from '@wwjVendor/upload/upload.service';
import { PayService } from '@wwjVendor/pay/pay.service';
import { SmsService } from '@wwjVendor/sms/sms.service';
import { NoticeService } from '@wwjVendor/notice/notice.service';

@Injectable()
export class CoreWeappDeliveryService extends BaseService<any> {
  private readonly logger = new Logger(CoreWeappDeliveryService.name);

  constructor(
    @InjectRepository(Object)
    protected readonly repository: Repository<any>,
    private readonly cacheService: CacheService,
    private readonly configService: ConfigService,
    private readonly loggingService: LoggingService,
    private readonly uploadService: UploadService,
    private readonly payService: PayService,
    private readonly smsService: SmsService,
    private readonly noticeService: NoticeService,
  ) {
    super(repository);
  }

  /**
   * isTradeManaged
   * 对应 PHP: CoreWeappDeliveryService_core::isTradeManaged()
   * 逻辑类型: undefined - undefined
   */
  async isTradeManaged(site_id: number) {
    // 基于PHP真实逻辑: isTradeManaged
    // PHP原文: $app = CoreWeappService::app($site_id);         $account = $app->getAccount();         $appid = $account->getAppId();         return $app->getClient()...
const app = CoreWeappService.app(site_id];
        const account = app.getAccount(];
        const appid = account.getAppId();
        return app.getClient().postJson('wxa/sec/order/is_trade_managed', [ appid: appid )).toArray(];
    }

    /**
     * 发货信息录入接口
     * 文档：https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#一、发货信息录入接口
     * 用户交易后，默认资金将会进入冻结状态，开发者在发货后，需要在小程序平台录入相关发货信息，平台会将发货信息以消息的形式推送给购买的微信用户。
     * 如果你已经录入发货信息，在用户尚未确认收货的情况下可以通过该接口修改发货信息，但一个支付单只能更新一次发货信息，请谨慎操作。
     * 如暂时没有完成相关API的对接开发工作，你也可以登陆小程序的后台，通过发货信息管理页面手动录入发货信息。
     * 注意事项
     * 1、根据指定的订单单号类型，采用不同参数给指定订单上传物流信息：
     *      (1). 商户侧单号形式（枚举值1），通过下单商户号和商户侧单号确定一笔订单
     *      (2). 微信支付单号形式（枚举值2），通过微信支付单号确定一笔订单
     * 2、发货模式根据具体发货情况选择：
     *      (1). 统一发货（枚举值1），一笔订单统一发货，只有一个物流单号。
     *      (2). 分拆发货（枚举值2），一笔订单分拆发货，包括多个物流单号。
     * 3、物流公司编码，参见获取运力 id 列表get_delivery_list。
     *      https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_search.html#%E8%8E%B7%E5%8F%96%E8%BF%90%E5%8A%9Bid%E5%88%97%E8%A1%A8get-delivery-list
     * 4、上传时间，用于标识请求的先后顺序，如果要更新物流信息，上传时间必须比之前的请求更新，请按照 RFC 3339 格式填写。
     * 5、分拆发货仅支持使用物流快递发货，一笔支付单最多分拆成 10 个包裹。
     * 6、以下情况将视为重新发货，每笔支付单仅有一次重新发货机会。
     *      (1). 对已完成发货的支付单再次调用该 API。
     *      (2). 使用该 API 修改发货模式或物流模式。
     * @param int site_id
     * @param params
     * @return mixed
     * @throws InvalidArgumentBusinessException
     */
    async uploadShippingInfo(int site_id, params = [))
    {
        try {

            const pay_service = this.payChannelService;
            const pay_config = pay_service.getInfo([
                type: PayDict.WECHATPAY,
                channel: ChannelDict.WEAPP
            )];

            const mch_id = '';
            if (!!pay_config)) {
                const mch_id = pay_config[ 'config' ][ 'mch_id' ];
            }

            const data = [
                order_key: [
                    order_number_type: 1, // 订单单号类型，用于确认需要上传详情的订单。枚举值1，使用下单商户号和商户侧单号；枚举值2，使用微信支付单号。
                    mchid: mch_id, // 支付下单商户的商户号，由微信支付生成并下发。
                    out_trade_no: params[ 'out_trade_no' ] // 商户系统内部订单号，只能是数字、大小写字母`_-*`且在同一个商户号下唯一
                ],
                logistics_type: params[ 'logistics_type' ], // 物流模式，发货方式枚举值：1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
                delivery_mode: params[ 'delivery_mode' ], // 发货模式，发货模式枚举值：1、UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货） 示例值: UNIFIED_DELIVERY
                // 同城配送没有物流信息，只能传一个订单
                shipping_list: params[ 'shipping_list' ], // 物流信息列表，发货物流单列表，支持统一发货（单个物流单）和分拆发货（多个物流单）两种模式，多重性: [1, 10]
                upload_time: date("c", time()), // 上传时间，用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00`
                payer: [
                    openid: params[ 'weapp_openid' ] // 用户标识，用户在小程序appid下的唯一标识。 下单前需获取到用户的Openid 示例值: oUpF8uMuAJO_M2pxb1Q9zNjWeS6o 字符字节限制: [1, 128]
                ],
                is_all_delivered: params[ 'is_all_delivered' ] // 分拆发货模式时必填，用于标识分拆发货模式下是否已全部发货完成，只有全部发货完成的情况下才会向用户推送发货完成通知。示例值: true/false
            ];

            Log.write('发货信息录入接口，参数打印：' . json_encode(data)];

            //微信订单录入有时差 延时3秒执行发货通知
            sleep(3];

            const api = CoreWeappService.appApiClient(site_id);
            const result = api.postJson('wxa/sec/order/upload_shipping_info', data).toArray(];

            Log.write('发货信息录入接口，返回结果：' . json_encode(result)];

            return result;
  }

  /**
   * uploadShippingInfo
   * 对应 PHP: CoreWeappDeliveryService_core::uploadShippingInfo()
   * 逻辑类型: undefined - undefined
   */
  async uploadShippingInfo(site_id: any[], params: any[]) {
    // 基于PHP真实逻辑: uploadShippingInfo
    // PHP原文: try {              $pay_service = new PayChannelService();             $pay_config = $pay_service->getInfo([                 'type' => PayDict::WECHAT...
try {

            const pay_service = this.payChannelService;
            const pay_config = pay_service.getInfo([
                type: PayDict.WECHATPAY,
                channel: ChannelDict.WEAPP
            )];

            const mch_id = '';
            if (!!pay_config)) {
                const mch_id = pay_config[ 'config' ][ 'mch_id' ];
            }

            const data = [
                order_key: [
                    order_number_type: 1, // 订单单号类型，用于确认需要上传详情的订单。枚举值1，使用下单商户号和商户侧单号；枚举值2，使用微信支付单号。
                    mchid: mch_id, // 支付下单商户的商户号，由微信支付生成并下发。
                    out_trade_no: params[ 'out_trade_no' ] // 商户系统内部订单号，只能是数字、大小写字母`_-*`且在同一个商户号下唯一
                ],
                logistics_type: params[ 'logistics_type' ], // 物流模式，发货方式枚举值：1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
                delivery_mode: params[ 'delivery_mode' ], // 发货模式，发货模式枚举值：1、UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货） 示例值: UNIFIED_DELIVERY
                // 同城配送没有物流信息，只能传一个订单
                shipping_list: params[ 'shipping_list' ], // 物流信息列表，发货物流单列表，支持统一发货（单个物流单）和分拆发货（多个物流单）两种模式，多重性: [1, 10]
                upload_time: date("c", time()), // 上传时间，用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00`
                payer: [
                    openid: params[ 'weapp_openid' ] // 用户标识，用户在小程序appid下的唯一标识。 下单前需获取到用户的Openid 示例值: oUpF8uMuAJO_M2pxb1Q9zNjWeS6o 字符字节限制: [1, 128]
                ],
                is_all_delivered: params[ 'is_all_delivered' ] // 分拆发货模式时必填，用于标识分拆发货模式下是否已全部发货完成，只有全部发货完成的情况下才会向用户推送发货完成通知。示例值: true/false
            ];

            Log.write('发货信息录入接口，参数打印：' . json_encode(data)];

            //微信订单录入有时差 延时3秒执行发货通知
            sleep(3];

            const api = CoreWeappService.appApiClient(site_id);
            const result = api.postJson('wxa/sec/order/upload_shipping_info', data).toArray(];

            Log.write('发货信息录入接口，返回结果：' . json_encode(result)];

            return result;
  }

  /**
   * notifyConfirmReceive
   * 对应 PHP: CoreWeappDeliveryService_core::notifyConfirmReceive()
   * 逻辑类型: undefined - undefined
   */
  async notifyConfirmReceive(site_id: any[], params: any[]) {
    // 基于PHP真实逻辑: notifyConfirmReceive
    // PHP原文: try {              $pay_service = new PayChannelService();             $pay_config = $pay_service->getInfo([                 'type' => PayDict::WECHAT...
try {

            const pay_service = this.payChannelService;
            const pay_config = pay_service.getInfo([
                type: PayDict.WECHATPAY,
                channel: ChannelDict.WEAPP
            )];

            const mch_id = '';
            if (!!pay_config)) {
                const mch_id = pay_config[ 'config' ][ 'mch_id' ];
            }

            const data = [
                merchant_id: mch_id, // 支付下单商户的商户号，由微信支付生成并下发
                merchant_trade_no: params[ 'out_trade_no' ], // 商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一
                received_time: time() // 快递签收时间，时间戳形式
            ];

            Log.write('确认收货提醒接口，参数打印：' . json_encode(data)];

            //微信订单录入有时差 延时3秒执行发货通知
            sleep(3];

            const api = CoreWeappService.appApiClient(site_id);

            const result = api.postJson('wxa/sec/order/notify_confirm_receive', data).toArray(];

            Log.write('确认收货提醒接口，返回结果：' . json_encode(result)];
            return result;
  }

  /**
   * setMsgJumpPath
   * 对应 PHP: CoreWeappDeliveryService_core::setMsgJumpPath()
   * 逻辑类型: undefined - undefined
   */
  async setMsgJumpPath(site_id: number, type: number) {
    // 基于PHP真实逻辑: setMsgJumpPath
    // PHP原文: $config_data = $this->getConfig($site_id, $type);         if (true || empty($config_data) || ( !empty($config_data[ 'value' ]) && empty($config_data[ ...
const config_data = this.getConfig(site_id, type);
        if (true || !config_data) || ( !!config_data[ 'value' )) && !config_data[ 'value' ][ 'path' )) )) {
            try {
                const path = 'app/pages/weapp/order_shipping';
                const api = CoreWeappService.appApiClient(site_id);
                const result = api.postJson('wxa/sec/order/set_msg_jump_path', [ path: path )];
                if (typeof result[ 'errcode' )) && result[ 'errcode' ] == 0) {
                    const data = [
                        path: path
                    ];
                    this.setConfig(site_id, type, data);
                }

                return result;
            } catch (\BusinessException e) {
    // 待实现
  }
  }

  /**
   * getDeliveryList
   * 对应 PHP: CoreWeappDeliveryService_core::getDeliveryList()
   * 逻辑类型: undefined - undefined
   */
  async getDeliveryList(site_id: number) {
    // 基于PHP真实逻辑: getDeliveryList
    // PHP原文: $api = CoreWeappService::appApiClient($site_id);         return $api->postJson('cgi-bin/express/delivery/open_msg/get_delivery_list', [ 'request' => '...
const api = CoreWeappService.appApiClient(site_id);
        return api.postJson('cgi-bin/express/delivery/open_msg/get_delivery_list', [ request: 'post' )).toArray(];
    }

    /**
     * todo 暂无使用
     * 查询订单发货状态
     * 你可以通过交易单号或商户号+商户单号来查询该支付单的发货状态。
     * 文档：https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#三、查询订单发货状态
     * @param int site_id
     * @param params
     * @return mixed
     * @throws InvalidArgumentBusinessException
     */
    async getOrder(int site_id, params = [))
    {
        const api = CoreWeappService.appApiClient(site_id);
        return api.postJson('wxa/sec/order/get_order', params).toArray(];
    }

    /**
     * todo 暂无使用
     * 查询订单列表
     * 你可以通过支付时间、支付者openid或订单状态来查询订单列表。
     * 文档：https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#四、查询订单列表
     * @param int site_id
     * @param params
     * @return mixed
     * @throws InvalidArgumentBusinessException
     */
    async getOrderList(int site_id, params = [))
    {
        const api = CoreWeappService.appApiClient(site_id);
        return api.postJson('wxa/sec/order/get_order_list', params).toArray(];
    }

    /**
     * 获取配置信息
     * @param int site_id
     * @param string type
     * @return */
    async getConfig(int site_id, type)
    {
        const config_service = this.coreConfigService;
        const res = config_service.getConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type);
        return res;
    }

    /**
     * 设置配置
     * @param int site_id
     * @param string type
     * @param value
     * @return SysConfig|bool|Model
     */
    async setConfig(int site_id, type, value)
    {
        const config_service = this.coreConfigService;
        const res = config_service.setConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type, value);
        return res;
    }

}
  }

  /**
   * getOrder
   * 对应 PHP: CoreWeappDeliveryService_core::getOrder()
   * 逻辑类型: undefined - undefined
   */
  async getOrder(site_id: any[], params: any[]) {
    // 基于PHP真实逻辑: getOrder
    // PHP原文: $api = CoreWeappService::appApiClient($site_id);         return $api->postJson('wxa/sec/order/get_order', $params)->toArray();     }      /**      * t...
const api = CoreWeappService.appApiClient(site_id);
        return api.postJson('wxa/sec/order/get_order', params).toArray(];
    }

    /**
     * todo 暂无使用
     * 查询订单列表
     * 你可以通过支付时间、支付者openid或订单状态来查询订单列表。
     * 文档：https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#四、查询订单列表
     * @param int site_id
     * @param params
     * @return mixed
     * @throws InvalidArgumentBusinessException
     */
    async getOrderList(int site_id, params = [))
    {
        const api = CoreWeappService.appApiClient(site_id);
        return api.postJson('wxa/sec/order/get_order_list', params).toArray(];
    }

    /**
     * 获取配置信息
     * @param int site_id
     * @param string type
     * @return */
    async getConfig(int site_id, type)
    {
        const config_service = this.coreConfigService;
        const res = config_service.getConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type);
        return res;
    }

    /**
     * 设置配置
     * @param int site_id
     * @param string type
     * @param value
     * @return SysConfig|bool|Model
     */
    async setConfig(int site_id, type, value)
    {
        const config_service = this.coreConfigService;
        const res = config_service.setConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type, value);
        return res;
    }

}
  }

  /**
   * getOrderList
   * 对应 PHP: CoreWeappDeliveryService_core::getOrderList()
   * 逻辑类型: undefined - undefined
   */
  async getOrderList(site_id: any[], params: any[]) {
    // 基于PHP真实逻辑: getOrderList
    // PHP原文: $api = CoreWeappService::appApiClient($site_id);         return $api->postJson('wxa/sec/order/get_order_list', $params)->toArray();     }      /**    ...
const api = CoreWeappService.appApiClient(site_id);
        return api.postJson('wxa/sec/order/get_order_list', params).toArray(];
    }

    /**
     * 获取配置信息
     * @param int site_id
     * @param string type
     * @return */
    async getConfig(int site_id, type)
    {
        const config_service = this.coreConfigService;
        const res = config_service.getConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type);
        return res;
    }

    /**
     * 设置配置
     * @param int site_id
     * @param string type
     * @param value
     * @return SysConfig|bool|Model
     */
    async setConfig(int site_id, type, value)
    {
        const config_service = this.coreConfigService;
        const res = config_service.setConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type, value);
        return res;
    }

}
  }

  /**
   * getConfig
   * 对应 PHP: CoreWeappDeliveryService_core::getConfig()
   * 逻辑类型: undefined - undefined
   */
  async getConfig(site_id: number, type: number) {
    // 基于PHP真实逻辑: getConfig
    // PHP原文: $config_service = new CoreConfigService();         $res = $config_service->getConfig($site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . $type);         return...
const config_service = this.coreConfigService;
        const res = config_service.getConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type);
        return res;
    }

    /**
     * 设置配置
     * @param int site_id
     * @param string type
     * @param value
     * @return SysConfig|bool|Model
     */
    async setConfig(int site_id, type, value)
    {
        const config_service = this.coreConfigService;
        const res = config_service.setConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type, value);
        return res;
    }

}
  }

  /**
   * setConfig
   * 对应 PHP: CoreWeappDeliveryService_core::setConfig()
   * 逻辑类型: undefined - undefined
   */
  async setConfig(site_id: any[], type: any[], value: any[]) {
    // 基于PHP真实逻辑: setConfig
    // PHP原文: $config_service = new CoreConfigService();         $res = $config_service->setConfig($site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . $type, $value);       ...
const config_service = this.coreConfigService;
        const res = config_service.setConfig(site_id, 'WEAPP_ORDER_SHIPPING_CONFIG_' . type, value);
        return res;
    }

}
  }
}
